use rustcloud_core::*;
use rustcloud_core::config_builder::{RetryConfig, TimeoutConfig, ConfigFactory};
use rustcloud_registry::InMemoryRegistry;
use rustcloud_loadbalancer::{LoadBalancerManager, LoadBalancerStrategy};
use rustcloud_circuit_breaker::DefaultCircuitBreaker;
use rustcloud_transport::HttpTransport;
use std::sync::Arc;
use std::time::Duration;

/// 服务客户端 - 整合了注册中心、负载均衡、熔断器和传输层
pub struct ServiceClient {
    registry: Arc<dyn ServiceRegistry>,
    load_balancer: LoadBalancerManager,
    circuit_breaker: Arc<DefaultCircuitBreaker>,
    transport: Arc<HttpTransport>,
    config: ClientConfig,
}

#[derive(Debug, Clone)]
pub struct ClientConfig {
    pub load_balancer_strategy: LoadBalancerStrategy,
    pub circuit_breaker_enabled: bool,
    pub timeout: Duration,
    pub retries: u32,
    pub retry_delay: Duration,
}

impl Default for ClientConfig {
    fn default() -> Self {
        // 使用统一的配置构建器创建标准配置
        let retry_config = ConfigFactory::create_fast_retry();
        let timeout_config = TimeoutConfig::builder()
            .request_timeout(Duration::from_secs(5))
            .build()
            .expect("Failed to build timeout config");
            
        Self {
            load_balancer_strategy: LoadBalancerStrategy::RoundRobin,
            circuit_breaker_enabled: true,
            timeout: timeout_config.request_timeout,
            retries: retry_config.max_attempts,
            retry_delay: retry_config.base_delay,
        }
    }
}

impl ServiceClient {
    /// 创建新的服务客户端
    pub fn new(config: ClientConfig) -> Self {
        let registry = Arc::new(InMemoryRegistry::new());
        let load_balancer = LoadBalancerManager::new(config.load_balancer_strategy);
        let circuit_breaker_config = CircuitBreakerConfig::default();
        let circuit_breaker = Arc::new(DefaultCircuitBreaker::new(circuit_breaker_config));
        let transport = Arc::new(HttpTransport::new(
            config.timeout,
            config.retries,
            config.retry_delay,
        ));

        Self {
            registry,
            load_balancer,
            circuit_breaker,
            transport,
            config,
        }
    }

    /// 注册服务实例
    pub async fn register_service(&self, instance: ServiceInstance) -> ServiceResult<()> {
        self.registry.register(instance).await
    }

    /// 发现服务实例
    pub async fn discover_service(&self, service_name: &str) -> ServiceResult<Vec<ServiceInstance>> {
        self.registry.discover(service_name).await
    }

    /// 注销服务实例
    pub async fn deregister_service(&self, instance: ServiceInstance) -> ServiceResult<()> {
        self.registry.deregister(instance).await
    }

    /// 调用服务
    pub async fn call_service(&self, request: Request) -> ServiceResult<Response> {
        let service_name = request.service_name.clone();
        let instances = self.discover_service(&service_name).await?;

        if instances.is_empty() {
            return Err(ServiceError::NoAvailableInstances(service_name.clone()));
        }

        let selected_instance = self.load_balancer.select_instance(&service_name, &instances).await?;
        let instance = selected_instance.ok_or_else(|| {
            ServiceError::NoAvailableInstances(service_name.clone())
        })?;

        let transport = self.transport.clone();
        let circuit_breaker = self.circuit_breaker.clone();
        let instance = instance.clone();
        let request = request.clone();

        if self.config.circuit_breaker_enabled {
            circuit_breaker.call(&service_name, move || {
                let transport = transport.clone();
                let instance = instance.clone();
                let request = request.clone();
                Box::pin(async move {
                    transport.send(request, &instance).await
                })
            }).await
        } else {
            transport.send(request, instance).await
        }
    }

    /// 批量调用服务
    pub async fn call_services(&self, requests: Vec<Request>) -> Vec<ServiceResult<Response>> {
        let mut results = Vec::new();
        for request in requests {
            let result = self.call_service(request).await;
            results.push(result);
        }
        results
    }

    /// 获取熔断器状态
    pub fn circuit_breaker_state(&self, service_name: &str) -> CircuitBreakerState {
        self.circuit_breaker.state(service_name)
    }

    /// 获取熔断器指标
    pub fn circuit_breaker_metrics(&self, service_name: &str) -> CircuitBreakerMetrics {
        self.circuit_breaker.metrics(service_name)
    }

    /// 获取负载均衡策略
    pub fn load_balancer_strategy(&self) -> LoadBalancerStrategy {
        self.load_balancer.strategy()
    }

    /// 设置负载均衡策略
    pub fn set_load_balancer_strategy(&mut self, strategy: LoadBalancerStrategy) {
        self.config.load_balancer_strategy = strategy;
        self.load_balancer.set_strategy(strategy);
    }
}

/// 服务客户端构建器
pub struct ServiceClientBuilder {
    config: ClientConfig,
}

impl ServiceClientBuilder {
    pub fn new() -> Self {
        Self {
            config: ClientConfig::default(),
        }
    }

    pub fn load_balancer_strategy(mut self, strategy: LoadBalancerStrategy) -> Self {
        self.config.load_balancer_strategy = strategy;
        self
    }

    pub fn circuit_breaker_enabled(mut self, enabled: bool) -> Self {
        self.config.circuit_breaker_enabled = enabled;
        self
    }

    pub fn timeout(mut self, timeout: Duration) -> Self {
        self.config.timeout = timeout;
        self
    }

    pub fn retries(mut self, retries: u32) -> Self {
        self.config.retries = retries;
        self
    }

    pub fn retry_delay(mut self, delay: Duration) -> Self {
        self.config.retry_delay = delay;
        self
    }

    pub fn build(self) -> ServiceClient {
        ServiceClient::new(self.config)
    }
}

impl Default for ServiceClientBuilder {
    fn default() -> Self {
        Self::new()
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn test_service_client_registration_and_discovery() {
        let client = ServiceClient::new(ClientConfig::default());
        let instance = ServiceInstance::new("test-service", "127.0.0.1", 8080, "http");
        
        client.register_service(instance.clone()).await.unwrap();
        let instances = client.discover_service("test-service").await.unwrap();
        
        assert_eq!(instances.len(), 1);
        assert_eq!(instances[0].service_id, "test-service");
        assert_eq!(instances[0].host, "127.0.0.1");
        assert_eq!(instances[0].port, 8080);
        
        client.deregister_service(instance).await.unwrap();
        let instances = client.discover_service("test-service").await.unwrap();
        assert_eq!(instances.len(), 0);
    }

    #[tokio::test]
    async fn test_service_client_builder() {
        let client = ServiceClientBuilder::new()
            .load_balancer_strategy(LoadBalancerStrategy::Random)
            .circuit_breaker_enabled(false)
            .timeout(Duration::from_secs(10))
            .retries(0)
            .retry_delay(Duration::from_millis(500))
            .build();
        
        assert_eq!(client.load_balancer_strategy(), LoadBalancerStrategy::Random);
        assert!(!client.config.circuit_breaker_enabled);
        assert_eq!(client.config.timeout, Duration::from_secs(10));
        assert_eq!(client.config.retries, 0);
        assert_eq!(client.config.retry_delay, Duration::from_millis(500));
    }
}